
module  led
  (
    input                               clk                        ,
    output                           uart_txd                   ,
    input    [9:0]                 ms1224_10bit               ,
    output    reg                       ms1224_refclk_25M          ,
    input                               ms1224_rclk                ,
    output reg led_v,
    output reg led_d,
    output reg led_l,
    input                               ms1224_lock
  );
  reg [7:0]   tx_data;
  reg  [9:0]  dout;
  reg [7:0] bit_counter = 8'd0; // ????????
  reg ld = 1'b0; // ??????1
  reg fal = 1'b1; // ?????????0
  reg [1:0] sync_cn = 2'd0; // ?????

  reg [1:0] fr_state = 2'd0; //?????

  parameter align = 2'd2; // ???
  parameter loss = 2'd1;  // ??
  parameter search = 2'd3;  // ?????

  reg [7:0] ms1224_bit9; // ?9?????????
  reg [7:0] ms1224_bit8; // ?8??????????
  reg [7:0] ms1224_bit7; // ?7????????
  reg [7:0] ms1224_bit6; // ?6????????
  reg [7:0] ms1224_bit5; // ?5????????
  reg [7:0] ms1224_bit4; // ?4????????
  reg [7:0] ms1224_bit3; // ?3????????
  reg [7:0] ms1224_bit2; // ?2????????
  reg [7:0] ms1224_bit1; // ?1????????
  reg [7:0] ms1224_bit0; // ?0????????

  // assign tx_data = {ld,fal,sync_cn[1:0],fr_state[1:0],ms1224_10bit[9:8]};

  always @(posedge clk)
  begin
    ms1224_refclk_25M <= ~ms1224_refclk_25M;
  end

  always @(posedge ms1224_rclk)
  begin
    dout[9] = ms1224_bit9[0];
    dout[8] = ms1224_bit8[0];
    dout[7] = ms1224_bit7[0];
    dout[6] = ms1224_bit6[0];
    dout[5] = ms1224_bit5[0];
    dout[4] = ms1224_bit4[0];
    dout[3] = ms1224_bit3[0];
    dout[2] = ms1224_bit2[0];
    dout[1] = ms1224_bit1[0];
    dout[0] = ms1224_bit0[0];

    ms1224_bit9[7] <= ms1224_10bit[9];
    ms1224_bit9[6] <= ms1224_bit9[7];
    ms1224_bit9[5] <= ms1224_bit9[6];
    ms1224_bit9[4] <= ms1224_bit9[5];
    ms1224_bit9[3] <= ms1224_bit9[4];
    ms1224_bit9[2] <= ms1224_bit9[3];
    ms1224_bit9[1] <= ms1224_bit9[2];
    ms1224_bit9[0] <= ms1224_bit9[1];

    ms1224_bit8[7] <= ms1224_10bit[8];
    ms1224_bit8[6] <= ms1224_bit8[7];
    ms1224_bit8[5] <= ms1224_bit8[6];
    ms1224_bit8[4] <= ms1224_bit8[5];
    ms1224_bit8[3] <= ms1224_bit8[4];
    ms1224_bit8[2] <= ms1224_bit8[3];
    ms1224_bit8[1] <= ms1224_bit8[2];
    ms1224_bit8[0] <= ms1224_bit8[1];

    ms1224_bit7[7] <= ms1224_10bit[7];
    ms1224_bit7[6] <= ms1224_bit7[7];
    ms1224_bit7[5] <= ms1224_bit7[6];
    ms1224_bit7[4] <= ms1224_bit7[5];
    ms1224_bit7[3] <= ms1224_bit7[4];
    ms1224_bit7[2] <= ms1224_bit7[3];
    ms1224_bit7[1] <= ms1224_bit7[2];
    ms1224_bit7[0] <= ms1224_bit7[1];
    
    ms1224_bit6[7] <= ms1224_10bit[6];
    ms1224_bit6[6] <= ms1224_bit6[7];
    ms1224_bit6[5] <= ms1224_bit6[6];
    ms1224_bit6[4] <= ms1224_bit6[5];
    ms1224_bit6[3] <= ms1224_bit6[4];
    ms1224_bit6[2] <= ms1224_bit6[3];
    ms1224_bit6[1] <= ms1224_bit6[2];
    ms1224_bit6[0] <= ms1224_bit6[1];

    ms1224_bit5[7] <= ms1224_10bit[5];
    ms1224_bit5[6] <= ms1224_bit5[7];
    ms1224_bit5[5] <= ms1224_bit5[6];
    ms1224_bit5[4] <= ms1224_bit5[5];
    ms1224_bit5[3] <= ms1224_bit5[4];
    ms1224_bit5[2] <= ms1224_bit5[3];
    ms1224_bit5[1] <= ms1224_bit5[2];
    ms1224_bit5[0] <= ms1224_bit5[1];
    
    ms1224_bit4[7] <= ms1224_10bit[4];
    ms1224_bit4[6] <= ms1224_bit4[7];
    ms1224_bit4[5] <= ms1224_bit4[6];
    ms1224_bit4[4] <= ms1224_bit4[5];
    ms1224_bit4[3] <= ms1224_bit4[4];
    ms1224_bit4[2] <= ms1224_bit4[3];
    ms1224_bit4[1] <= ms1224_bit4[2];
    ms1224_bit4[0] <= ms1224_bit4[1];

    ms1224_bit3[7] <= ms1224_10bit[3];
    ms1224_bit3[6] <= ms1224_bit3[7];
    ms1224_bit3[5] <= ms1224_bit3[6];
    ms1224_bit3[4] <= ms1224_bit3[5];
    ms1224_bit3[3] <= ms1224_bit3[4];
    ms1224_bit3[2] <= ms1224_bit3[3];
    ms1224_bit3[1] <= ms1224_bit3[2];
    ms1224_bit3[0] <= ms1224_bit3[1];
    
    ms1224_bit2[7] <= ms1224_10bit[2];
    ms1224_bit2[6] <= ms1224_bit2[7];
    ms1224_bit2[5] <= ms1224_bit2[6];
    ms1224_bit2[4] <= ms1224_bit2[5];
    ms1224_bit2[3] <= ms1224_bit2[4];
    ms1224_bit2[2] <= ms1224_bit2[3];
    ms1224_bit2[1] <= ms1224_bit2[2];
    ms1224_bit2[0] <= ms1224_bit2[1];

    ms1224_bit1[7] <= ms1224_10bit[1];
    ms1224_bit1[6] <= ms1224_bit1[7];
    ms1224_bit1[5] <= ms1224_bit1[6];
    ms1224_bit1[4] <= ms1224_bit1[5];
    ms1224_bit1[3] <= ms1224_bit1[4];
    ms1224_bit1[2] <= ms1224_bit1[3];
    ms1224_bit1[1] <= ms1224_bit1[2];
    ms1224_bit1[0] <= ms1224_bit1[1];
    
    ms1224_bit0[7] <= ms1224_10bit[0];
    ms1224_bit0[6] <= ms1224_bit0[7];
    ms1224_bit0[5] <= ms1224_bit0[6];
    ms1224_bit0[4] <= ms1224_bit0[5];
    ms1224_bit0[3] <= ms1224_bit0[4];
    ms1224_bit0[2] <= ms1224_bit0[3];
    ms1224_bit0[1] <= ms1224_bit0[2];
    ms1224_bit0[0] <= ms1224_bit0[1];
  end
  always @(posedge ms1224_rclk)
  begin
    if(bit_counter == 8'd254)
      ld <= 1'b0;
    else
    begin
      ld <= 1'b1;
    end

    if(ms1224_bit9 == 8'b11011001)
    begin
      case(fr_state)
        loss:
        begin
          fal <= 1'b1;
          if(ms1224_bit9 == 8'b11011001)
          begin
            fr_state <= search;
            bit_counter <= 8'd1;
            sync_cn <= 2'd0;
          end
          else
          begin
            bit_counter <= 8'd254;
          end
        end
        search :
        begin
          fal <= 1'b1;
          if(bit_counter == 0)
          begin
            if(ms1224_bit9 != 8'b11011001)
            begin
              fr_state <= loss;
              bit_counter <= 8'd254;
            end
            else
            begin
              sync_cn <= sync_cn + 1;
              bit_counter <= bit_counter + 1;
              if(sync_cn == 2'd3)
              begin

                fr_state <= align;
                sync_cn <= 0;
              end
            end
          end
          else
            bit_counter <= bit_counter + 1;
        end
        align :
        begin
          fal <= 1'b0;
          if(bit_counter == 8'd0)
          begin
            if(ms1224_bit9 != 8'b11011001)
            begin
              sync_cn <= sync_cn + 1;
              bit_counter <= bit_counter + 1;
              if(sync_cn == 2'd3)
                fr_state <= loss;
              else
                sync_cn <= 2'd0;
            end
            else
              bit_counter <= bit_counter + 1;
          end
          else
            bit_counter <= bit_counter + 1;
        end
        default:
        begin
          fal <= 1'b1;
          fr_state <= loss;
          bit_counter <= 8'd254;
        end
      endcase
    end
  end


  reg [2:0]  bit_cnt = 3'd0;
  reg [7:0]  bit9;

  reg [7:0]  bit8;
  reg [7:0]  bit7;
  reg [7:0]  bit6;
  reg [7:0]  bit5;
  reg [7:0]  bit4;
  reg [7:0]  bit3;
  reg [7:0]  bit2;
  reg [7:0]  bit1;
  reg [7:0]  bit0;
  // ??
  reg [9:0]  d1_reg = 10'b1010101010;

  always @(posedge ms1224_rclk)
  begin
    if(ld == 1'b0) begin
      bit_cnt <= 0;
      d1_reg <= 10'b1010101010;
    end
    else
    begin
      bit_cnt <= bit_cnt + 1;
      d1_reg <= d1_reg ^ 10'b1111111111;
      // bit9[bit_cnt] <= dout[7];
      bit8[bit_cnt] <= dout[8] ^ d1_reg[8];
      bit7[bit_cnt] <= dout[7] ^ d1_reg[7];
      bit6[bit_cnt] <= dout[6] ^ d1_reg[6];
      bit5[bit_cnt] <= dout[5] ^ d1_reg[5];
      bit4[bit_cnt] <= dout[4] ^ d1_reg[4];
      bit3[bit_cnt] <= dout[3] ^ d1_reg[3];
      bit2[bit_cnt] <= dout[2] ^ d1_reg[2];
      bit1[bit_cnt] <= dout[1] ^ d1_reg[1];
      bit0[bit_cnt] <= dout[0] ^ d1_reg[0];
      led_l <= bit1[bit_cnt];
      led_d <= bit3[bit_cnt];
    end
  end



  wire tx9_nege;
  wire ready;

  always @(posedge clk)
  begin
    if(ms1224_bit9 == 8'b11011001)
      led_v <= 1'b0;
    else
      led_v <= 1'b1;
  end

  assign tx9_nege = (ms1224_bit9 == 8'b11011001) && ready;
  uart_tx uart_tx_inst(
    .clk			      (clk),
    .rst			      (1'b0),
    .tx_data 	      (bit4),
    .tx_data_vld	      (tx9_nege),
    .ready   	      (ready),
    .tx           (uart_txd)
  );

endmodule
